import re
import argparse
import time
import sys
import subprocess
import os
import configparser


class Sqlsmith:

    def __init__(self):
        self.cf = configparser.ConfigParser()
        self.start_time = time.time()
        self.return_code = 0

    def parse_command_line(self):
        parser = argparse.ArgumentParser()
        parser.description = "openGauss sqlsmith CI"
        parser.add_argument("-d", "--ConfigPath", help="ConfigFilePath")
        config_file_path = parser.parse_args().ConfigPath

        self.cf.read(config_file_path)
        self.db_port = self.cf.get("profile", "db_port")
        self.sqlsmith_database = self.cf.get("profile", "sqlsmith_database")
        self.sqlsmith_user = self.cf.get("profile", "sqlsmith_user")
        self.userpasswd = self.cf.get("profile", "userpasswd")
        self.database_ip = self.cf.get("profile", "database_ip")

    def run_sqlsmith(self):
        self.parse_command_line()
        cmd = './sqlsmith --verbose --target="host=%s port=%s dbname=%s' \
              ' user=%s password=%s"' % \
              (self.database_ip, self.db_port, self.sqlsmith_database,
               self.sqlsmith_user, self.userpasswd)
        print(cmd)
        process = subprocess.Popen(cmd, shell=True,
                  stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
        while True:
            rcode = process.poll()
            if rcode is None:
                line = process.stderr.readline().strip()
                line_content = line.decode()
                print(line_content)
                if (self.parse_and_print_sqlsmith_result(line_content) == -1):
                    process.kill()
                    self.return_code = -1
                    return -1
            else:
                print(rcode)
                break
        return 0

    @staticmethod
    def parse_and_print_sqlsmith_result(self, ss_result):
        # 跳过空行
        if ss_result is None or len(ss_result.strip()) == 0:
            return
        ss_result = ss_result.strip()

        # 校验sqlsmith结果
        if re.match(".*C{5,}$", ss_result):
            print("sqlsmith ended with failure!")
            return -1
        else:
            return 0

if __name__ == '__main__':
    sqlsmith = Sqlsmith()
    sqlsmith.run_sqlsmith()

    print("sqlsmith end!")
    print(sqlsmith.return_code)
    sys.exit(sqlsmith.return_code)